<script setup lang="ts">
import {ShallowRef} from "vue";
import {OrbitControls, Stars,} from "@tresjs/cientos";
import {useRenderLoop, useTresContext} from "@tresjs/core";
import {TresControl, TresScene} from "@tresjs/core/dist/src/types";
import {Camera} from "three";
import * as THREE from 'three'

import {ThemeVO} from "@/api/pb/theme";

import {useLoaderStorage} from "@/store/modules/web3d/loader";

const loader = useLoaderStorage()

const { scene, camera, controls } =  useTresContext()

/** 赋值场景、相机、控制器 */
const injectScene = inject<ShallowRef<TresScene>>('scene')!
const injectCamera = inject<ShallowRef<Camera>>('camera')!
const injectControls = inject<ShallowRef<TresControl>>('controls')!
// 场景监听
const stopSceneWatch = watchEffect(() => {
  if (scene.value) {
    injectScene.value = scene.value
  }
})
// 相机监听
const stopCameraWatch = watchEffect(() => {
  if (camera.value) {
    injectCamera.value = camera.value
  }
})
// 控制器监听
const stopControlsWatch = watchEffect(() => {
  if (controls.value) {
    injectControls.value = controls.value
  }
})

/** 是否正在操作控制器 */
const controlling = inject<Ref<boolean>>('controlling')!
const setControlling = (value: boolean) => {
  setTimeout(() => {
    controlling.value = value
  }, 100)
}

/** 旋转的星空 */
const yRotation = shallowRef(0)
useRenderLoop().onLoop(({ delta }) => {
  yRotation.value += 0.02 * delta
})

// 默认网格大小
const gridSideLength = inject<number>('gridSideLength')!
// 主题数据
const theme = inject<Ref<ThemeVO>>('theme')!
// 实际大小
const gridH = ref(0)
const gridW = ref(0)
const positionH = gridSideLength * 4
const gridHelperPosition = ref<[number, number, number][]>([])

// 初始化
const stopInitWatch = watch([theme, camera, controls], ([theme, camera, controls]) => {
  if(theme && camera && controls) {
    loader.loader(() => {
      gridH.value = gridSideLength * theme.grid.h
      gridW.value = gridSideLength * theme.grid.w

      // 计算中心偏移量
      const offsetX = -gridW.value / 2 + gridSideLength / 2;
      const offsetY = 0; // 不需要偏移，保持为0
      const offsetZ = -gridH.value / 2 + gridSideLength / 2;

      for (let i = 0; i < theme.grid.h; i++) {
        for (let j = 0; j < theme.grid.w; j++) {
          gridHelperPosition.value.push([
            gridSideLength * j + offsetX,
            offsetY,
            gridSideLength * i + offsetZ,
          ]);
        }
      }

      const h = (theme.grid.h - 1) / 2 * gridSideLength
      const w = (theme.grid.w - 1) / 2 * gridSideLength
      const targetPoint = new THREE.Vector3(w, 0, h)

      const angleInRadians = Math.PI / 4
      const distanceFromTarget = positionH / Math.tan(angleInRadians)

      camera.position.set(
        targetPoint.x + distanceFromTarget * Math.cos(angleInRadians),
        positionH,
        targetPoint.z + distanceFromTarget * Math.sin(angleInRadians)
      )

      controls.target.copy(targetPoint)
      controls.update()

      stopInitWatch()
    })

  }
}, { immediate: true})

/** TODO 有问题 不显示 */
/** 场景指示器 */
// const viewHelperRef = ref()
// const addViewHelper = () => {
//   renderer.value.autoClear = false
//   const viewHelper = new ViewHelper(camera.value!, renderer.value!, "bottom-right")
//   viewHelper.setControls(controls.value)
//   viewHelperRef.value = viewHelper
// }
// const stopAddViewHelperWatch = watch(
//   [camera, renderer, controls],
//   ([camera, renderer, controls]) => {
//     if (camera && renderer && controls) {
//       addViewHelper()
//       stopAddViewHelperWatch()
//     }
//   }
// )

onUnmounted(() => {
  scene.value.clear()
})

</script>

<template>
  <TresPerspectiveCamera />
  <TresAmbientLight :intensity="1" />
  <OrbitControls
    make-default
    @start="setControlling(true)"
    @end="setControlling(false)"
  />
  <Stars
    :rotation="[0, yRotation, 0]"
    :radius="50"
    :depth="500"
    :count="5000"
    :size="0.3"
    :size-attenuation="true"
  />

  <template v-if="theme">
    <TresGridHelper
      v-for="(position, index) in gridHelperPosition"
      :key="index"
      :args="[gridSideLength, gridSideLength]"
      :position="position"
    />
  </template>

</template>

<style scoped lang="scss">

</style>
